package com.os.opencv.java.chapter9;

import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.util.ArrayList;
import java.util.List;

public class MinAreaRect {

    public static void main(String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        //读取图像并在屏幕上显示
        Mat src = Imgcodecs.imread("/Users/matt/Pictures/erzhi.jpg", Imgcodecs.IMREAD_GRAYSCALE);

        Mat binary = new Mat();
        Imgproc.threshold(src, binary, 90, 255, Imgproc.THRESH_BINARY);

        //在屏幕上显示二值图像
        HighGui.imshow("binary", binary);
        HighGui.waitKey(0);

        //根据二值图检测轮廓
        List<MatOfPoint> contour = new ArrayList<>();
        Imgproc.findContours(binary, contour, new Mat(), Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);

        //重新获取彩色图像，用于绘制最小外接矩形
        src = Imgcodecs.imread("/Users/matt/Pictures/erzhi.jpg");

        //参数准备
        MatOfPoint2f dst = new MatOfPoint2f();
        Mat pts = new Mat();
        Scalar red = new Scalar(0,0,255);
        float[] data = new float[8];
        for(int n=0; n<contour.size(); n++){
            //将轮廓数据转换为MatOfPoint2f
            contour.get(n).convertTo(dst, CvType.CV_32F);
            //获取在校外接矩形
            RotatedRect rect = Imgproc.minAreaRect(dst);

            //获取矩形的4个顶点
            Imgproc.boxPoints(rect, pts);
            pts.get(0,0,data);
            //将4个顶点转换为Point类
            Point pt1 = new Point(data[0], data[1]);
            Point pt2 = new Point(data[2], data[3]);
            Point pt3 = new Point(data[4], data[5]);
            Point pt4 = new Point(data[6], data[7]);

            //绘制最小外接矩形的4条边
            Imgproc.line(src, pt1, pt2, red, 2);
            Imgproc.line(src, pt2, pt3, red, 2);
            Imgproc.line(src, pt3, pt4, red, 2);
            Imgproc.line(src, pt4, pt1, red, 2);
        }

        //在屏幕上显示绘有最小外接矩形的图像
        HighGui.imshow("minarearect", src);
        HighGui.waitKey(0);

        System.exit(0);

    }
}
